<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../js/vue.global.js"></script>
</head>

<body>
    <div id="app">
        
        <p>{{zhang.name}}---{{zhang.age}}---{{zhang.info.height}}---{{zhang.info.weight}}</p>
        <p>
            <button @click="changeName">changeName</button>
            <button @click="changeAge">changeAge</button>
            <button @click="changeHeight">changeHeight</button>
        </p>
    </div>
</body>
<script>
    // Vue3  => Vue的第三个大版本修改  
    // 相较于Vue2  
    // 1. 选项式语法做了修改  



    // Vue3
    // 1. Vue  => 全局对象  => {createApp,nextTick,ref,reactive}
    // 2. Vue中对象存有创建引用的方法  var {createApp} = Vue;
    // 3. Vue3的选项式语法中 没有el属性 => 通过app.mount() 指定挂载的元素
    // 4. Vue3的选项式语法中 data是一个返回对象的函数  => 所有的组件均是如此 
    // 5. Vue3中 data methods computed 不在存储在Vue组件(实例)上  => 而是单独存储到一个对象上(代理对象 proxy)  =>  方法中的this默认都指向代理对象  => 取值和赋值都通过代理对象执行
    // 6. Vue3中 全局属性 组件 指令 插件 都是依赖于app定义的

    // 组合式语法

    console.log(Vue);

    var { createApp, getCurrentInstance } = Vue;
    var { ref, reactive } = Vue;
    var { shallowReactive , triggerRef} = Vue;
    var app = createApp({
        // 组合式
        setup: function (props) {
            console.log("setup钩子函数开始执行");
            // props  在组件通信过程中,用于接收父组件传入数据的属性
            // 在组合式语法中 可以定义数据(data) methods, 计算属性, 绑定监听, 绑定生命周期钩子函数 => 完成选项式相同的效果  
            // 组合式语法中抛弃了this =>直接对应数据修改

            // 如何定义数据?



            // 定义普通变量  => 问题: Vue无法监听变量的值发生改变 => 不会更新视图
            // var a = 10;
            // function addA(){
            //     a++;
            //     console.log(1111,a);
            // }

            // reactive()  => 创建一个对对象的引用=>返回的是proxy对象/响应对象
            // 操作proxy对象(取值/赋值) => 会同步更新到源对象 
            // Vue响应式 对reactive对象的拦截默认也是深层的  => 无论是reactive对象上的根属性发生改变,还是根属性下某个对象的子属性发生改变都会触发视图更新

            // Vue响应式 对shallowReactive对象的拦截默认也是浅层的  => 只拦截reactive对象上的根属性发生的改变,如果是根属性下某个对象的子属性发生改变,不会触发视图更新

            // new Proxy(target,{get,set})
            // var zhang = reactive({ name: "张飒", age: 18, info: { height: 177, weight: 70 } });
            var zhang = shallowReactive({ name: "张飒", age: 18, info: { height: 177, weight: 70 } });
        
            console.log("reactive", zhang);
            console.log("proxy取值", zhang.name);
            console.log("proxy取值", zhang.age);

            var app = getCurrentInstance();
            var {ctx} = app;


            // 定义方法 methods
            function changeName() {
                zhang.name = '李四'
            }
            function changeAge() {
                zhang.age++
            }
            function changeHeight() {
                zhang.info.height++
                console.log( zhang.info.height);
                ctx.$forceUpdate();
            }



            // 闭包  => setup函数中返回的数据/计算属性/方法/监听  就是后面选项式语法中接收的
            // 对象中的键名 => 后面选项式语法中proxy代理对象中的属性名
            // 对象中的键值 => setup函数中的对象 方法
            return {
                zhang: zhang, // zhang:proxy对象(zhang)
                changeName: changeName,
                changeAge: changeAge,
                changeHeight,
            }
        },
        // 选项式
        // data(){},
        // computed:{},
        // methods:{},
        // watch:{},

        beforeCreate() {
            console.log("beforeCreate", this);
            // console.log("beforeCreate",this.a);  // proxy对象取值是进行了解包  this.a => ref.value;

            // this.a = 100;   // ref.value = 100;
            // console.log("beforeCreate",this.a); // this.a => ref.value;

        },
    })

    console.log("app", app);
    app.mount("#app");




</script>



</html>